package leetcode

import kotlinetc.println

//https://leetcode.com/problems/search-a-2d-matrix/

/**
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

Integers in each row are sorted from left to right.
The first integer of each row is greater than the last integer of the previous row.
Example 1:

Input:
matrix = [
[1,   3,  5,  7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 3
Output: true
Example 2:

Input:
matrix = [
[1,   3,  5,  7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 13
Output: false
 */
fun main(args: Array<String>) {

    val matrix = arrayOf(
            intArrayOf(1, 3, 5, 7),
            intArrayOf(10, 11, 16, 20),
            intArrayOf(23, 30, 34, 50)
    )
    searchMatrix(matrix, 51).println()
}

//由于行之间是有序的，先二分查找 是那一行，让后在具体的某一行再使用二分查找

fun searchMatrix(matrix: Array<IntArray>, target: Int): Boolean {
    if (matrix.isEmpty()||matrix[0].isEmpty())return false

    //binary search row

    var l = 0
    var r = matrix.size - 1

    var mid = (l + r + 1) / 2

    while (l <= r) {
        if (target < matrix[mid].first())
            r = mid - 1
        else if (target > matrix[mid].last())
            l = mid + 1
        else break  //just mid !
        mid = (l + r + 1) / 2
    }

    if (r < 0 || l > matrix.lastIndex) return false

    var row = mid

    l = 0
    r = matrix[row].lastIndex

    mid = (l + r + 1) / 2

    var found = false

    while (l <= r) {

        if (target == matrix[row][mid]) {
            found = true
            break
        }

        if (target < matrix[row][mid])
            r = mid - 1
        else l = mid

        //虽然在本行，但可能没有这个数字
        if (target < matrix[row][l] || target > matrix[row][r])
            break

        mid = (l + r + 1) / 2
    }

    return found.also { if (it) println("found!") }

}